﻿using System;
using System.Collections.Generic;
using System.Transactions;
using Bingosoft.Data;
using HHMMS.WorkFlow.Model;
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data.Common;
using System.Data;

namespace HHMMS.WorkFlow.Service
{
	/// <summary>
	///表示对表WorkflowInstance的所有操作的实现。
	/// </summary>
    public class WorkflowInstanceService
    {
        private readonly Dao dao = Dao.Get();

        private WorkflowInstanceService()
        { }

        private static WorkflowInstanceService instance = null;
        /// <summary>
        /// WorkflowInstance服务类的单例。
        /// </summary>
        public static WorkflowInstanceService Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (typeof(WorkflowInstanceService))
                    {
                        instance = new WorkflowInstanceService();
                    }
                }
                return instance;
            }
        }

        public void Delete(string instanceId)
        {
            this.dao.ExecuteNonQuery("workflow.workflowinstance.delete", new
            {
                InstanceId = instanceId
            });
        }

        public void Insert(WorkflowInstance workflowInstance)
        {
            this.dao.ExecuteNonQuery("workflow.workflowinstance.insert", workflowInstance);
        }

        public void Update(WorkflowInstance workflowInstance)
        {
            this.dao.ExecuteNonQuery("workflow.workflowinstance.update", workflowInstance);
        }

        public WorkflowInstance Single(string instanceId)
        {
            return this.dao.QueryEntity<WorkflowInstance>("workflow.workflowinstance.single", new
            {
                InstanceId = instanceId
            });
        }

        /// <summary>
        /// 创建流程实例并返回流程编号。
        /// </summary>
        /// <param name="workflowId">待创建的流程ID</param>
        /// <param name="instanceName">实例名称</param>
        /// <param name="dataKey">关联的业务数据主键</param>
        /// <param name="creatorId">创建人</param>
        /// <param name="creatorId">意见或说明</param>
        /// <returns>返回流程编号</returns>
        public string CreateInstance(int workflowId, string instanceName, string dataKey, string creatorId, string partComment)
        {
            Database db = dao.Database;
            DbCommand cmd = db.GetStoredProcCommand("USP_WF_CreateInstance");
            db.AddInParameter(cmd, "@WorkflowId", DbType.Int32, workflowId);
            db.AddInParameter(cmd, "@InstanceName", DbType.String, instanceName);
            db.AddInParameter(cmd, "@DataKey", DbType.String, dataKey);
            db.AddInParameter(cmd, "@CreatorId", DbType.String, creatorId);
            db.AddInParameter(cmd, "@PartComment", DbType.String, partComment);
            db.AddOutParameter(cmd, "@InstanceId", DbType.String, 15);
            db.ExecuteNonQuery(cmd);
            return db.GetParameterValue(cmd, "@InstanceId") + "";
        }

        /// <summary>
        /// 运行工作流实例。
        /// </summary>
        /// <param name="instanceId">待运行的工作流实例ID</param>
        /// <param name="taskId">当前任务ID</param>
        /// <param name="partIds">下一步骤参与者</param>
        /// <param name="partChoice">当前步骤的审批结果</param>
        /// <param name="partComment">当前步骤的审批意见</param>
        /// <returns>返回下一环节ID</returns>
        public int RunInstance(string instanceId, int taskId, string partIds, string partChoice, string partComment)
        {
            Database db = dao.Database;
            DbCommand cmd = db.GetStoredProcCommand("USP_WF_RunInstance");
            db.AddInParameter(cmd, "@InstanceID", DbType.String, instanceId);
            db.AddInParameter(cmd, "@TaskID", DbType.Int32, taskId);
            db.AddInParameter(cmd, "@PartIDs", DbType.String, partIds);
            db.AddInParameter(cmd, "@PartChoice", DbType.String, partChoice);
            db.AddInParameter(cmd, "@PartComment", DbType.String, partComment);
            db.AddOutParameter(cmd, "@NextActivityId", DbType.Int32, 0);
            db.ExecuteNonQuery(cmd);
            return (int)db.GetParameterValue(cmd, "@NextActivityId");
        }

        /// <summary>
        /// 作废流程实例。
        /// </summary>
        /// <param name="instanceId">待作废的流程实例ID</param>
        /// <param name="taskId">当前任务ID</param>
        /// <param name="partComment">作废原因</param>
        public void DiscardInstance(string instanceId, int taskId, string partComment)
        {
            Database db = dao.Database;
            DbCommand cmd = db.GetStoredProcCommand("USP_WF_DiscardInstance");
            db.AddInParameter(cmd, "@InstanceID", DbType.String, instanceId);
            db.AddInParameter(cmd, "@TaskID", DbType.Int32, taskId);
            db.AddInParameter(cmd, "@PartComment", DbType.String, partComment);
            db.ExecuteNonQuery(cmd);
        }
    }
}